a11y: Move relationset updating to new vfunc
authorBenjamin Otte <otte@redhat.com>
Mon, 24 Mar 2014 15:34:08 +0000 (16:34 +0100)
committerBenjamin Otte <otte@redhat.com>
Mon, 24 Mar 2014 15:38:18 +0000 (16:38 +0100)
This way, we don't create lots of cell accessibles when creating the
first one (because surely one is the parent/child of another who again
is a parent/child of another who again....)

gtk/a11y/gtktreeviewaccessible.c

index 5a5b11a16f6ff9e790d1d267ca2a7dd5d67e2873..47180175e544cb25d9d5d7069321d8de5fad3d18 100644 (file)
@@ -427,29 +427,6 @@ create_cell (GtkTreeView           *treeview,
   set_cell_data (treeview, accessible, cell);
   _gtk_cell_accessible_update_cache (cell);
 
-  if (gtk_tree_view_get_expander_column (treeview) == column)
-    {
-      AtkRelationSet *relation_set;
-      AtkRelation* relation;
-      AtkObject *parent_node;
-
-      relation_set = atk_object_ref_relation_set (ATK_OBJECT (cell));
-
-      if (tree->parent_tree)
-        {
-          parent_node = ATK_OBJECT (peek_cell (accessible, tree->parent_tree, tree->parent_node, column));
-          if (parent_node == NULL)
-            parent_node = ATK_OBJECT (create_cell (treeview, accessible, tree->parent_tree, tree->parent_node, column));
-        }
-      else
-        parent_node = ATK_OBJECT (accessible);
-      relation = atk_relation_new (&parent_node, 1, ATK_RELATION_NODE_CHILD_OF);
-      atk_relation_set_add (relation_set, relation);
-      atk_object_add_relationship (parent_node, ATK_RELATION_NODE_PARENT_OF, ATK_OBJECT (cell));
-      g_object_unref (relation);
-      g_object_unref (relation_set);
-    }
-
   return cell;
 }
 
@@ -1354,6 +1331,73 @@ gtk_tree_view_accessible_edit (GtkCellAccessibleParent *parent,
                          TRUE);
 }
 
+static void
+gtk_tree_view_accessible_update_relationset (GtkCellAccessibleParent *parent,
+                                             GtkCellAccessible       *cell,
+                                             AtkRelationSet          *relationset)
+{
+  GtkTreeViewAccessibleCellInfo *cell_info;
+  GtkTreeViewAccessible *accessible;
+  GtkTreeViewColumn *column;
+  GtkTreeView *treeview;
+  AtkRelation *relation;
+  GtkRBTree *tree;
+  GtkRBNode *node;
+  AtkObject *object;
+
+  /* Don't set relations on cells that aren't direct descendants of the treeview.
+   * So only set it on the container, not on the renderer accessibles */
+  if (atk_object_get_parent (ATK_OBJECT (cell)) != ATK_OBJECT (parent))
+    return;
+
+  accessible = GTK_TREE_VIEW_ACCESSIBLE (parent);
+  cell_info = find_cell_info (accessible, cell);
+  if (!cell_info)
+    return;
+
+  /* only set parent/child rows on the expander column */
+  treeview = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)));
+  column = gtk_tree_view_get_expander_column (treeview);
+  if (column != cell_info->cell_col_ref)
+    return;
+
+  /* Update CHILD_OF relation to parent cell */
+  relation = atk_relation_set_get_relation_by_type (relationset, ATK_RELATION_NODE_CHILD_OF);
+  if (relation)
+    atk_relation_set_remove (relationset, relation);
+
+  if (cell_info->tree->parent_tree)
+    {
+      object = ATK_OBJECT (peek_cell (accessible, cell_info->tree->parent_tree, cell_info->tree->parent_node, column));
+      if (object == NULL)
+        object = ATK_OBJECT (create_cell (treeview, accessible, cell_info->tree->parent_tree, cell_info->tree->parent_node, column));
+    }
+  else
+    object = ATK_OBJECT (accessible);
+
+  atk_relation_set_add_relation_by_type (relationset, ATK_RELATION_NODE_CHILD_OF, object);
+
+  /* Update PARENT_OF relation for all child cells */
+  relation = atk_relation_set_get_relation_by_type (relationset, ATK_RELATION_NODE_PARENT_OF);
+  if (relation)
+    atk_relation_set_remove (relationset, relation);
+
+  tree = cell_info->node->children;
+  if (tree)
+    {
+      for (node = _gtk_rbtree_first (tree);
+           node != NULL;
+           node = _gtk_rbtree_next (tree, node))
+        {
+          object = ATK_OBJECT (peek_cell (accessible, tree, node, column));
+          if (object == NULL)
+            object = ATK_OBJECT (create_cell (treeview, accessible, tree, node, column));
+
+          atk_relation_set_add_relation_by_type (relationset, ATK_RELATION_NODE_PARENT_OF, ATK_OBJECT (object));
+        }
+    }
+}
+
 static void
 gtk_cell_accessible_parent_interface_init (GtkCellAccessibleParentIface *iface)
 {
@@ -1365,6 +1409,7 @@ gtk_cell_accessible_parent_interface_init (GtkCellAccessibleParentIface *iface)
   iface->expand_collapse = gtk_tree_view_accessible_expand_collapse;
   iface->activate = gtk_tree_view_accessible_activate;
   iface->edit = gtk_tree_view_accessible_edit;
+  iface->update_relationset = gtk_tree_view_accessible_update_relationset;
 }
 
 void